#include "view.h"
#include "animation.h"

#include <string.h>
#include <stdio.h>
#include <memory.h>
#include <stdlib.h>

#include <libxml/parser.h>
#include <libxml/tree.h>
#include <libxml/xmlmemory.h>

#include "scrollbar.h"
#include "log.h"

typedef struct _SCROLLBAR
{
	int contentLength;
	int position;
	int orientation;
    UFO_View thumb;
    
    UFO_Animation animation;
}SCROLLBAR;

int ufoScrollBarHide(UFO_View view)
{
	SCROLLBAR *pScrollBar = ufoViewGetUserData(view);
	if (pScrollBar) {
        if (!ufoViewGetMask(view, UFO_VIEW_BIT_HIDDEN) && UFO_ANIMATION_PLAYING != ufoAnimationGetState(pScrollBar->animation)) {
            UFO_Animation_Value value = {Animation_alpha};
            value.alpha = 0.0f;
            ufoAnimationSetToValue(pScrollBar->animation, value);
            ufoAnimationSetDuration(pScrollBar->animation, 300);
            ufoAnimationSetTimingFunction(pScrollBar->animation, TimingFunctionEaseOut);
            ufoAnimationPlay(pScrollBar->animation);
        }
        else {
            ufoViewSetAlpha(view, 0.0f);
        }
	}
	return 1;
}

int ufoScrollBarShow(UFO_View view)
{
	SCROLLBAR *pScrollBar = ufoViewGetUserData(view);
	if (pScrollBar) {
        ufoAnimationStop(pScrollBar->animation);
        ufoViewSetAlpha(view, 1.0f);
	}
	return 1;
}

void internal_adjust_thumb(UFO_View view)
{
    SCROLLBAR *pScrollBar = ufoViewGetUserData(view);
	if (pScrollBar) {
        UFO_View parentView = ufoViewGetParent(view);
        //ufoLog("scrollbar", "scrollbar length = %d position = %d",
         //      pScrollBar->contentLength, pScrollBar->position);
        
        if (parentView && pScrollBar->contentLength) {
				
			ufoRect rcScrollBar = {0};
            ufoRect rcThumb = {0};
            int height = 0;
			int length = 0;
			int topThumb = 0;

            ufoViewGetRect(pScrollBar->thumb, &rcThumb);
			ufoViewGetRect(view, &rcScrollBar);
			height = pScrollBar->orientation == SCROLLBAR_VERT ?
            rcScrollBar.bottom-rcScrollBar.top : rcScrollBar.right-rcScrollBar.left;
			length = height*height/pScrollBar->contentLength;

			length = length < 7 ? 7:length;

			if (pScrollBar->position+height > pScrollBar->contentLength) {
				pScrollBar->position = pScrollBar->contentLength-height;
			}

			if (pScrollBar->contentLength <= height) {//### content less than scrollview
				pScrollBar->position = 0;
				length = height;
                ufoScrollBarHide(view);
                //ufoViewSetMask(view, UFO_VIEW_BIT_HIDDEN, 1);
			}
            else {
                //ufoViewSetMask(view, UFO_VIEW_BIT_HIDDEN, 0);
                ufoScrollBarShow(view);
            }

			if (height == length)
				topThumb = 0;
			else
				topThumb = pScrollBar->position*(height-length)/(pScrollBar->contentLength-height);

			if (pScrollBar->orientation == SCROLLBAR_VERT) {//## vert
                rcThumb.top = topThumb;
                rcThumb.bottom = topThumb+length;
            }
            else if (pScrollBar->orientation == SCROLLBAR_HORZ) {//## horz
                rcThumb.left = topThumb;
                rcThumb.right = topThumb+length;		
            }

			ufoViewSetRect(pScrollBar->thumb, &rcThumb);
            //ufoLog("scrollbar", "top = %f bottom = %f", rcThumb.top, rcThumb.bottom);
        }
    }
}

int ufoScrollBarSetOrientation(UFO_View view, int orientation)
{
 	SCROLLBAR *pScrollBar = ufoViewGetUserData(view);
	if (pScrollBar) {
		if (pScrollBar->orientation != orientation) {
			pScrollBar->orientation = orientation;
            
            if (orientation == SCROLLBAR_VERT) {
                //ufoRect margin = {0, 0, 1, 0};
                ufoViewSetAnchor(view, ANCHOR_RIGHT|ANCHOR_TOP|ANCHOR_BOTTOM);
                ufoViewSetAnchor(pScrollBar->thumb, ANCHOR_LEFT|ANCHOR_RIGHT);
                //ufoViewSetMargin(view, &margin);
                ufoViewSetBackground(pScrollBar->thumb, ufoResourceGetTexture("b"));
            }
            else {
                //ufoRect margin = {0, 0, 0, 1};
                ufoViewSetAnchor(view, ANCHOR_BOTTOM|ANCHOR_LEFT|ANCHOR_RIGHT);
                ufoViewSetAnchor(pScrollBar->thumb, ANCHOR_TOP|ANCHOR_BOTTOM);
                //ufoViewSetMargin(view, &margin);
                ufoViewSetBackground(pScrollBar->thumb, ufoResourceGetTexture("b"));
            }
            
            internal_adjust_thumb(view);
		}
	}
	return 1;
}

int ufoScrollBarSetPosition(UFO_View view, int position)
{
	SCROLLBAR *pScrollBar = ufoViewGetUserData(view);
	if (pScrollBar) {
		if (pScrollBar->position != position) {
			pScrollBar->position = position;
            internal_adjust_thumb(view);
		}
	}
	return 1;
}

int ufoScrollBarSetLength(UFO_View view, int length)
{
	SCROLLBAR *pScrollBar = ufoViewGetUserData(view);
	if (pScrollBar) {
		if (pScrollBar->contentLength != length) {
			pScrollBar->contentLength = length;
			internal_adjust_thumb(view);
		}
	}
	return 1;
}

int default_scrollBar_proc(UFO_View view, int id, void* wParam, void* lParam)
{
	SCROLLBAR *pScrollBar = ufoViewGetUserData(view);
	if (!pScrollBar) {
		pScrollBar = malloc(sizeof(SCROLLBAR));
		memset(pScrollBar, 0, sizeof(SCROLLBAR));
		ufoViewSetUserData(view, pScrollBar);
	}

	switch (id)
	{
	case MSG_NOTIFY:
		{
			
		}
		break;

	case MSG_SIZE_CHANGE:
		{
            internal_adjust_thumb(view);
		}
		break;

	case MSG_XML:
		{
			ufoViewDefaultProc(view, id, wParam, lParam);
			{
				xmlNodePtr node = wParam;
				xmlChar *orientation = xmlGetProp(node, (const xmlChar*)"orientation");
				if (orientation) {
					if (xmlStrcmp(orientation, (const xmlChar*)"vert") == 0) {
						pScrollBar->orientation = 0;
					}
					else if (xmlStrcmp(orientation, (const xmlChar*)"horz") == 0) {
						pScrollBar->orientation = 1;
					}
					xmlFree(orientation);
				}
			}
		}
		return 1;

	case MSG_CREATE:
		{
            pScrollBar->thumb = ufoViewCreate(0);
            ufoViewAddChildView(view, pScrollBar->thumb);
            
            pScrollBar->animation = ufoAnimationCreate(view);
			break;
		}

	/*case MSG_TOUCH_ENTER:
		{
			if (pScrollBar->thumb) {
				ufoThumbAnimationShow(pScrollBar->thumb, 600, 0);
			}
			break;
		}

	case MSG_TOUCH_LEAVE:
		{
			if (pScrollBar->thumb) {
				ufoThumbAnimationHide(pScrollBar->thumb);
			}
			break;
		}

	case MSG_TOUCH_WHEEL:   
	case MSG_TOUCH_MOVE:  
	case MSG_TOUCH_DOWN:  
	case MSG_TOUCH_UP:
		{
			((UFO_TOUCH_STRUCT*)lParam)->bHandled = 1;//### not pass to parent view
		}break;*/
	}

	return ufoViewDefaultProc(view, id, wParam, lParam);//### pass to default view proc
}
